<template>
  <el-card class="box-card" id="Content">
    <div >
      <el-backtop  :bottom="100" style="color: #0a81fa"/>
      <div id="CT">
        <div  class="img_view">
          <div slot="header" class="clearfix">
            <!--<span style="font-size: 23px;font-weight: 600;color: white;font-family: '微软雅黑 Light'">检 测 按 钮：</span>-->

            <el-card class="box-card" style="display: flex">
              <div style="display: flex; align-items: center; gap: 16px;">
                <div>
                  <el-button
                          style="border-radius: 8px; margin-left: 35px"
                          type="primary"
                          icon="el-icon-upload"
                          class="download_bt"
                          v-on:click="true_upload2"
                  >
                    本地上传
                    <input
                            ref="upload2"
                            style="display: none"
                            name="file"
                            type="file"
                            @change="update"
                    />
                  </el-button>
                  <el-button
                          style="border-radius: 8px; margin-left: 25px"
                          v-show="showbutton"
                          type="primary"
                          icon="el-icon-view"
                          class="download_bt"
                          @click="getCompetence()"
                  >开启摄像头</el-button>
                  <el-button
                          style="border-radius: 8px; margin-left: 25px"
                          v-show="!showbutton"
                          type="primary"
                          icon="el-icon-error"
                          class="download_bt"
                          @click="stopNavigator()"
                  >关闭摄像头</el-button>
                  <el-button
                          style="border-radius: 8px; margin-left: 25px"
                          v-show="!showbutton"
                          type="primary"
                          icon="el-icon-camera"
                          class="download_bt"
                          @click="setImage()"
                  >拍照上传</el-button>
                  <el-button
                          style="border-radius: 8px; margin-left: 25px"
                          v-show="!showbutton"
                          type="primary"
                          icon="el-icon-cpu"
                          class="download_bt"
                          @click="setImageAuto()"
                  >自动化监测</el-button>
                  <el-button
                          style="border-radius: 8px;margin-left: 25px;margin-top: 15px;width: 120px"
                          type="primary"
                          class="download_bt"
                          @click="downloadImage()"
                  >下载最新结果</el-button>

                  <!--<el-switch-->
                          <!--:disabled="switchdisvalue"-->
                          <!--style="display: block; float: right; margin-top: 6px;padding-left: 1vw"-->
                          <!--v-show="!showbutton"-->
                          <!--v-model="switchvalue"-->
                          <!--active-color="#0a81fa"-->
                          <!--inactive-color="#ff4949"-->
                  <!--&gt;</el-switch>-->
                </div>
                <div v-if="curRecord.length>0" style="flex: 1;margin-left: 2vw">
                  <el-table
                          :data="curRecord"
                          style="width: 700px; text-align: center"
                          v-loading="loading"
                          element-loading-text="数据正在处理中，请耐心等待"
                          element-loading-spinner="el-icon-loading"
                          lazy
                  >
                    <el-table-column label="目标标签" width="150px" prop="label"></el-table-column>
                    <el-table-column label="目标位置" width="200px" prop="position">
                      <template slot-scope="scope">
                        {{myPosition(scope.row)}}
                      </template>
                    </el-table-column>
                    <el-table-column label="置信度" width="150px" prop="zxd"></el-table-column>
                  </el-table>
                </div>
              </div>
              </el-card>

          </div>
          <div id="CT_image">
            <el-card style="border-radius: 15px;">
              <div class="camera_outer"> <!--当videoFlag为true时，第一个<video>元素会被显示，当videoFlag为false时，第二个<video>元素会显示。-->
                <video v-show="videoFlag" ref="videoPlayer" controls :width="videoWidth" :height="videoHeight" style="border-radius: 8px;width: 456px;height: 320px;margin-bottom: -30px;margin-top: -32px;"></video>
                <video v-show="!videoFlag" id="videoCamera" :width="videoWidth" :height="videoHeight" autoplay style="border-radius: 8px;width: 456px;height: 320px;margin-bottom: -30px;margin-top: -32px;"></video>
                <canvas style="display:none;" id="canvasCamera" :width="videoWidth" :height="videoHeight" ></canvas>
              </div>
              <br><br>
              <div class="img_info_1" style="border-radius: 8px;margin-bottom: 20px;margin-top: -2px">
                <span style="color: white; letter-spacing: 8px">相机画面</span>
              </div>
            </el-card>
            <br>
            <el-card style="border-radius: 15px;">
              <div class="demo-image__preview1">
                <div
                    v-loading="loading"
                    element-loading-text="上传图片中"
                    element-loading-spinner="el-icon-loading"
                >
                  <el-image v-if="myflag"
                            :src="url_1"
                            class="image_1"
                            :preview-src-list="srcList"
                            style="border-radius: 8px 8px 8px 8px"
                  >
                    <div slot="error" >
                      <div slot="placeholder" class="error"></div>
                    </div>
                  </el-image>
                  <img v-else :src="url_2" alt="" class="image_1" style="width: 400px;height: 300px">
                  <!--<el-image v-else-->
                            <!--:src="url_2"-->
                            <!--class="image_1"-->
                            <!--:preview-src-list="[url_2]"-->
                            <!--style="border-radius: 8px 8px 8px 8px"-->
                  <!--&gt;-->
                  <!--</el-image>-->
                </div>
                <div class="img_info_1" v-show="!videoFlag" style="border-radius: 8px;margin-bottom: 20px;">
                  <!--<span style="color: white; letter-spacing: 8px">原始图像{{myflag}}</span>-->
                  <span style="color: white; letter-spacing: 8px">原始图像</span>
                </div>

                <div class="img_info_1" v-show="videoFlag" style="border-radius: 8px;margin-bottom: 20px;">
                  <span style="color: white; letter-spacing: 8px">检测结果</span>
                </div>
              </div>
            </el-card>
            <br>
            <el-card style="border-radius: 15px;">
              <div v-if="myflag" class="demo-image__preview2">
                <div
                    v-loading="loading"
                    element-loading-text="处理中,请耐心等待"
                    element-loading-spinner="el-icon-loading"
                >
                  <el-image
                      :src="url_2"
                      class="image_1"
                      :preview-src-list="srcList1"
                      style="border-radius: 8px;margin-left: -2px;width: 456px;"
                  >
                    <div slot="error">
                      <div slot="placeholder" class="error">{{ wait_return }}</div>
                    </div>
                  </el-image>
                </div>
                <div class="img_info_1" style="border-radius: 8px; margin-bottom: 20px;margin-left: -2px;">
                  <span style="color: white; letter-spacing: 8px">检测结果</span>
                  <br>
                </div>
              </div >
            </el-card>

          </div>
        </div>
      </div>

    </div>
  </el-card>
</template>

<script>
import axios from "axios";
// import { randomBytes } from "crypto";
/* import CameraVue from './Camera.vue';测试用，废弃
 */
export default {
  name: "Content",
  components: {
  },
  data() {
    return {
      intervalIdvideo:null,
      videoFlag:false,
      pageSize:10,
      curPage:1,
      pageList:[],
      myflag:true,
      user:{},
      curRecord:[],
      numAlert: 20,
      person_num: 0,
      //静态图片上传下载所需参数
      server_url: "http://127.0.0.1:5003",
      activeName: "first",
      active: 0,
      centerDialogVisible: true,
      url_1: "",
      url_2: "",
      textarea: "",
      srcList: [],
      srcList1: [],
      feature_list: [],
      feature_list_1: [],
      feat_list: [],
      jsonData: {}, // 定义一个空对象
      url: "",
      visible: false,
      wait_return: "等待上传",
      wait_upload: "等待上传",
      loading: false,
      table: false,
      isNav: false,
      showbutton: true,
      percentage: 0,
      n: 3,
      fullscreenLoading: false,
      opacitys: {
        opacity: 0,
      },
      dialogTableVisible: false,

      //摄像头截取所需参数
      videoWidth: 1280,
      videoHeight: 720,
      imgSrc: '',
      thisCancas: null,
      thisContext: null,
      thisVideo: null,

      camerafilename : "",

      //设置开关默认参数
      switchvalue: false,
      switchdisvalue: true,

      //设置自动模式定时器
      intervalId: null, // 定时器变量
      intervalTime: 1000, // 每隔1秒执行一次

      setImageAutoBoolean: true,
    };
  },
  created: function () {
    document.title = "基于深度学习的施工现场安全帽识别系统";
  },
  methods: {
    paging(pagenum){  // 进行分页显示数据的功能
      var len=this.feature_list.length;
      var pages=len/10+1;
      if (pagenum>pages)
        pagenum=pages;
      if (pagenum<1)
        pagenum=1;
      this.pageList = {...this.feature_list};
      this.pageList = Array.from(this.feature_list);
      console.log(this.pageList);
      this.pageList = this.pageList.slice(pagenum*10-10, pagenum*10);
      this.curPage=pagenum;
    },
    true_upload() {
      this.$refs.upload.click();
    },
    true_upload2() {
      this.$refs.upload2.click();
    },
    next() {
      this.active++;
    },
    playWarningSound() {
      const audio = new Audio('square-alarm.mp3');
      audio.play().catch((error) => {
        console.error('Audio playback failed:', error);
      });
    },

    // 获得目标文件
    getObjectURL(file) {
      var url = null;
      if (window.createObjcectURL != undefined) {
        url = window.createOjcectURL(file);
      } else if (window.URL != undefined) {
        url = window.URL.createObjectURL(file);
      } else if (window.webkitURL != undefined) {
        url = window.webkitURL.createObjectURL(file);
      }
      return url;
    },
    isVideoFile(file) {
      const videoMimeTypes = [
        'video/mp4',
        'video/mpeg',
        'video/quicktime',
        'video/x-msvideo',
        'video/x-flv',
        'video/webm',
        'video/3gpp'
      ];
      return videoMimeTypes.includes(file.type);
    },
    // 上传文件
    update(e) {
      //初始化值
      this.percentage = 0;
      this.dialogTableVisible = true;
      this.srcList = [];
      this.srcList1 = [];
      this.wait_return = "";
      this.wait_upload = "";
      this.feature_list = [];
      this.feat_list = [];
      this.fullscreenLoading = true;
      this.loading = true;
      //this.showbutton = false;
      this.person_num = 0;

      let file = e.target.files[0];
      if (this.isVideoFile(file)) {   //处理视频
        this.myflag=false;
        this.fullscreenLoading = false;
        this.dialogTableVisible = false;
        this.loading = false;
        this.videoFlag=true;
        const videoPlayer = this.$refs.videoPlayer;
        videoPlayer.src = URL.createObjectURL(file);
        videoPlayer.play();
        // 在Vue组件中的方法中添加以下代码
        const canvas = document.createElement('canvas');  //建一个canvas元素，并获取其2D渲染上下文ctx，用于后续在画布上绘制视频帧
        const ctx = canvas.getContext('2d');
        this.intervalIdvideo=setInterval(() => {
          ctx.drawImage(videoPlayer, 0, 0, canvas.width, canvas.height);
          const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
          const base64Data = canvas.toDataURL('image/png');
          axios.post(this.server_url + "/upload2", {file:base64Data}).then(res=>{
            console.log(res);
            this.curRecord = JSON.parse(res.data.list);        //解析从服务器响应中返回的列表数据
            this.curRecord.forEach(item => {
              item.img = res.data.draw_url.split("'")[1];
              this.addRecord(item)
            });
            this.url_2='data:image/png;base64,' + res.data.draw_url.split("'")[1];
          });
          if (videoPlayer.ended) {
            clearInterval(this.intervalIdvideo); // 清除定时器
            this.videoFlag=false;
            this.myflag=true;
          }
        }, 250);

      }else {
        this.url_1 = this.$options.methods.getObjectURL(file);
        this.srcList.push(this.url_1);
        let param = new FormData(); //创建form对象
        param.append("file", file, file.name); //通过append向form对象添加数据
        var timer = setInterval(() => {
          this.myFunc();
        }, 30);
        let config = {
          headers: {"Content-Type": "multipart/form-data"}, //服务器端接收到的数据将以多部分数据的形式进行解析
        }; //添加请求头
        axios
                .post(this.server_url + "/upload", param, config)
                .then((response) => {
                  this.percentage = 100;
                  clearInterval(timer);
                  this.url_2 = 'data:image/png;base64,' + response.data.draw_url.split("'")[1];
                  this.srcList1.push(this.url_2);
                  this.fullscreenLoading = false;
                  this.loading = false;
                  this.dialogTableVisible = false;
                  this.curRecord = JSON.parse(response.data.list);
                  this.curRecord.forEach(item => {
                    item.img = response.data.draw_url.split("'")[1];
                    this.addRecord(item)
                  });

                });
      }
    },
    myFunc() { // 设置进度条
      if (this.percentage + 33 < 99) {
        this.percentage = this.percentage + 33;
      } else {
        this.percentage = 99;
      }
    },


    getCompetence() {  //摄像头
        this.showbutton = false;
        var _this = this
        this.thisCancas = document.getElementById('canvasCamera')
        this.thisContext = this.thisCancas.getContext('2d')
        this.thisVideo = document.getElementById('videoCamera')
        // this.switchdisvalue = !this.switchdisvalue //必须开启摄像头才可以调整自动模式【功能更新，开关仅作为示意】
        // 旧版本浏览器可能根本不支持mediaDevices，我们首先设置一个空对象
        if (navigator.mediaDevices === undefined) {
          navigator.mediaDevices = {}
        }
        // 一些浏览器实现了部分mediaDevices，我们不能只分配一个对象
        // 使用getUserMedia，因为它会覆盖现有的属性。
        // 这里，如果缺少getUserMedia属性，就添加它。
        if (navigator.mediaDevices.getUserMedia === undefined) {
          navigator.mediaDevices.getUserMedia = function (constraints) {
            // 首先获取现存的getUserMedia(如果存在)
            var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia
            // 有些浏览器不支持，会返回错误信息
            // 保持接口一致
            if (!getUserMedia) {
              return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
            }
            // 否则，使用Promise将调用包装到旧的navigator.getUserMedia
            return new Promise(function (resolve, reject) {
              getUserMedia.call(navigator, constraints, resolve, reject)
            })
          }
        }
        var constraints = { audio: false, video: { width: this.videoWidth, height: this.videoHeight, transform: 'scaleX(-1)' } }  //限制条件
        navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {  //请求访问媒体设备
          // 旧的浏览器可能没有srcObject
          if ('srcObject' in _this.thisVideo) {
            _this.thisVideo.srcObject = stream
          } else {
            // 避免在新的浏览器中使用它，因为它正在被弃用。
            _this.thisVideo.src = window.URL.createObjectURL(stream)
          }
          _this.thisVideo.onloadedmetadata = function (e) {
            _this.thisVideo.play()
          }
        }).catch(err => {
          // eslint-disable-next-line no-console
          console.log(err)
        })
      },
      //  绘制图片（拍照检测功能）
      setImage() {

        var _this = this
        // 点击，canvas画图
        _this.thisContext.drawImage(_this.thisVideo, 0, 0, _this.videoWidth, _this.videoHeight)
        // 获取图片base64链接
        var image = this.thisCancas.toDataURL('image/png')
        _this.imgSrc = image
        this.$emit('refreshDataList', this.imgSrc)

        let n = this.n;
        this.percentage = 0;
        this.url_1 = "";
        this.srcList = [];
        this.srcList1 = [];
        this.wait_return = "";
        this.wait_upload = "";
        this.feature_list = [];
        this.feat_list = [];
        this.person_num = 0;

        this.camerafilename = this.getCurrentDateTime();

        let file = this.dataURLtoFile(this.imgSrc, "camerafile"+ this.camerafilename +".jpg");//存储文件时，重命名打上时间戳留档
        this.url_1 = this.$options.methods.getObjectURL(file);
        this.srcList.push(this.url_1);
        let param = new FormData(); //创建form对象
        param.append("file", file, file.name); //通过append向form对象添加数据
        var timer = setInterval(() => {
          this.myFunc();
        }, 30);
        let config = {
          headers: { "Content-Type": "multipart/form-data" },
        }; //添加请求头
        axios
          .post(this.server_url + "/upload", param, config)
          .then((response) => {
          this.percentage = 100;
          clearInterval(timer);
          this.url_2 = 'data:image/png;base64,'+response.data.draw_url.split("'")[1];
          this.srcList1.push(this.url_2);
            this.curRecord=JSON.parse(response.data.list);
            this.curRecord.forEach(item=>{
              if(item.label==='head'){
                this.n = this.n + 1;
                item.img=response.data.draw_url;
                this.addRecord(item);
                if (this.n === 5){
                  this.n = 0;
                  _this.playWarningSound();
                  _this.$message.warning('有未带安全帽的人员请立即处理');
                  }
                }
            });
        });

      },

      //使用JavaScript的Date对象获取当前日期和时间。
      //使用new Date()语句来创建一个Date对象，然后使用Date对象的各种方法来获取当前日期和时间的各个部分，如年、月、日、时、分、秒等。
      //将获取到的日期和时间部分拼接成一个纯数字的字符串。
      //使用字符串的拼接操作符（+）来将各个部分拼接在一起，并使用字符串的padStart()方法来在数字前添加0，以确保每个部分都是两位数。
      getCurrentDateTime() {
        const now = new Date()
        const year = now.getFullYear().toString()
        const month = (now.getMonth() + 1).toString().padStart(2, '0')
        const date = now.getDate().toString().padStart(2, '0')
        const hour = now.getHours().toString().padStart(2, '0')
        const minute = now.getMinutes().toString().padStart(2, '0')
        const second = now.getSeconds().toString().padStart(2, '0')
        return year + month + date + hour + minute + second
      },

      // 定义一个名为setImageAuto的函数
      setImageAuto() {
      this.myflag=!this.myflag
        this.intervalTime = 250// 设置定时器间隔时间为0.25秒
        if (this.setImageAutoBoolean) { // 如果设置自动轮播的开关为true
          this.switchvalue = !this.switchvalue // 切换轮播状态
          this.setImageAutoBoolean = !this.setImageAutoBoolean // 切换自动轮播的开关
          if (this.switchvalue) { // 如果轮播状态为true
            this.intervalId = setInterval(this.setImage, this.intervalTime) // 设置定时器，每隔0.25秒调用一次setImage函数
          }
        }
        else { // 如果设置自动轮播的开关为false
          this.switchvalue = !this.switchvalue // 切换轮播状态
          this.setImageAutoBoolean = !this.setImageAutoBoolean // 切换自动轮播的开关
          clearInterval(this.intervalId) // 清除定时器
        }
      },

      // base64转文件
      dataURLtoFile (dataurl, filename) {
        var arr = dataurl.split(',')                   //将输入的串（dataurl）分为两部分，即数据类型与实际的 Base64 数据
        var mime = arr[0].match(/:(.*?);/)[1]  //从数据类型部分获取文件的 MIME 类型（例如："image/jpeg", "text/plain" 等）
        var bstr = atob(arr[1])                       //使用 atob() 函数将 Base64 数据解码为二进制字符串
        var n = bstr.length
        var u8arr = new Uint8Array(n)                 //创建一个新的 Uint8Array 来存储二进制数据
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n)
        }
        return new File([u8arr], filename, { type: mime })
      },
      // 关闭摄像头
      stopNavigator () {
        this.showbutton = true;
        this.thisVideo.srcObject.getTracks()[0].stop()
        // this.switchdisvalue = !this.switchdisvalue //关闭摄像头自动禁用模式切换开关【功能更新，开关仅作为示意】
        this.switchvalue = false //并将开关切换到手动模式
      },

      addRecord(res){
        let config = {
          headers: { "Content-Type": "application/json" },
        };
          var form = {
            label: res.label,
            position: res.position,
            user: this.user.username,
            img: res.img,
            bz: '',
            zxd: res.zxd
          };
          axios.post("http://127.0.0.1:5003/addRecord", form, config).then(res => {
          showDataSummarize(res);
          });
      },

    downloadImage() {
      const a = document.createElement('a');
      a.href = this.url_2;
      a.download = 'image.jpg';
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
    },
    myPosition(item){
      var position=item.position;
      // console.log(position);
      //(x1:207.0,y1:78.0),(x2:334.0,y2:275.0)
      var p1=position.split("),(")[0],p2=position.split("),(")[1];
      var x1=p1.split(":")[1].split(",")[0],y1=p1.split(":")[2].split(")")[0];
      var x2=p2.split(":")[1].split(",")[0],y2=p2.split(":")[2].split(")")[0];
      console.log(x1+","+y1+"...."+x2+","+y2);
      // parseFloat(x1)*parseFloat(y1);
      const xax1 = parseFloat(x1);
      const xax2 = parseFloat(x2);
      const yax1 = parseFloat(y1);
      const yax2 = parseFloat(y2);
      if ((xax2-xax1)**2 + (yax2-yax1)**2 <= 1500 ){
          if (xax1+xax2 <= 320 && yax1+yax2 <= 222){
            return "左上远处"
          }else if (xax1+xax2 <= 320 && yax1+yax2 <= 444){
            return "左方远处"
          } else if (xax1+xax2 <= 320 && yax1+yax2 <= 666){
            return "左下远处"
          } else if (xax1+xax2 <= 660 && yax1+yax2 <= 222){
            return "上方远处"
          } else if (xax1+xax2 <= 660 && yax1+yax2 <= 444){
            return "前方远处"
          }else if (xax1+xax2 <= 660 && yax1+yax2 <= 666){
            return "下方远处"
          }else if (yax1+yax2 <= 222){
            return "右上远处"
          } else if (yax1+yax2 <= 444){
            return "右方远处"
          }else{
            return "右下远处"
          }
        }else{
          if (xax1+xax2 <= 320 && yax1+yax2 <= 222){
            return "左上"
          }else if (xax1+xax2 <= 320 && yax1+yax2 <= 444){
            return "左方"
          } else if (xax1+xax2 <= 320 && yax1+yax2 <= 666){
            return "左下"
          } else if (xax1+xax2 <= 660 && yax1+yax2 <= 222){
            return "上方"
          } else if (xax1+xax2 <= 660 && yax1+yax2 <= 444){
            return "前方"
          }else if (xax1+xax2 <= 660 && yax1+yax2 <= 666){
            return "下方"
          }else if (yax1+yax2 <= 222){
            return "右上"
          } else if (yax1+yax2 <= 444){
            return "右方"
          }else{
            return "右下"
          }
      }
    }
  },
  mounted() {
    this.user=JSON.parse(sessionStorage.getItem('user'))
  },
};
</script>


<style>
#Content {
  background:#00000054;
  padding: 6px;
  border-radius: 5px;
  width: 98%;
  margin: 0px auto 20px;
  /*margin-top: 40px;*/
  /*background: radial-gradient(circle, #bad4ef, #60a7ef);*/
}

#CT {
  display: flex;
  width: 100%;
  flex-wrap: wrap;
  justify-content: center;
}

/* 图像对比框 */
#CT_image {
  /*width: 500px;*/
  border-radius: 15px;
  display: flex;
  gap: 2vw;
  margin-left: 2vw;
  height: 50vh;
}
#CT_image el-card{
  display: inline-block;
  flex: 1;
}

.img_view{
  width: 100vw;
}

/*#CT_image .el-card{*/
  /*float: left;*/
/*}*/

.img_info_1 {
  height: 30px;
  width: 456px;
  text-align: center;
  background-color: #409EFF;
  line-height: 30px;
}

.demo-image__preview1 {
  width: 456px;
  float: left;
}

.demo-image__preview2 {
  width: 456px;
  float: right;
}


.error {
  height: 240px;
  margin: 30px;
  text-align: center;
}

div {
  display: block;
}

.download_bt {
  padding: 10px 16px !important;
  background-color: #409EFF;
}
.download_bt:hover {
  padding: 10px 16px !important;
  background-color: #0a81fa;
}

.img_view .el-card{
  display: flex;
}

.clearfix{
  margin-left: 2vw;
  margin-bottom: 3vh;
}

.tx_img {
    max-width: 100%;
  }

</style>
